<?php
namespace PsiFramework\Classes\Util\Object;

import("Classes.Util.Object.File");
import("Classes.Model.ModelInterface.IPrimitiveObject");
import("Classes.Util.Database.Query.SqlType");

use \PsiFramework\Classes\Util\Database\Query\SqlType;
use \PsiFramework\Classes\Model\ModelInterface\IPrimitiveObject;
use \PsiFramework\Classes\Util\Object\File;

/**
 * PsiFramework
 * Php Simple Framework
 *
 * @author Rémi San
 * @version beta
 */

/**
 * The Image class represents an image
 *
 * @package Util.Object
 */
class Image implements IPrimitiveObject
{

    protected /*File*/   $_file ;

    /**
     * Constructor
     *
     * @param     File    $file    the file which contains the image
     * @return    Image     instance
     */
    public function __construct(/*File*/ $file=null)
    {
        $this->_file = $file ;
    }

    /**
     * Resize the image and stores it in the corresponding directories
     *
     * @param     string    $name    the name of the image
     */
    public function createResizedPictures(/*string*/ $path, /*int*/ $targetWidth=200, /*int*/ $targetHeight=200)
    {
        $image = $this->getImage();

        //Original size of the image
        $imageSize = getimagesize($this->_file->getPath());
        $width = $imageSize[0] ;
        $height = $imageSize[1] ;
        
        $ratio = $targetWidth/$targetHeight;
        
        $newWidth = null;
        $newHeight = null;
        if ($width/$height < $ratio) {
            $newHeight = round($width/$ratio);
            $newWidth = $width;
        } else {
            $newWidth = round($height*$ratio);
            $newHeight = $height;
        }
        
        $x = round(($width-$newWidth)/2);
        $y = round(($height-$newHeight)/2);
        
        //Profile image creation
        $success = $this->resize(
            $path,
            $image,
            0,
            0,
            $x,
            $y,
            $targetWidth,
            $targetHeight,
            $newWidth,
            $newHeight,
            100
        );
        
        if ($success) {
            //Delete the image
            imagedestroy($image);
        }
        
        return $success;
    }

    /**
     * Resizes the image
     *
     * @param string    $filePath        the path where to save the image
     * @param image        $oldImage        the old image
     * @param int        $newX            the x origin for the new image
     * @param int        $newY            the y origin for the new image
     * @param int        $oldX            the x origin for the old image
     * @param int        $oldY            the y origin for the old image
     * @param int        $newWidth        the width of the new image
     * @param int        $newHeight        the height of the new image
     * @param int        $oldWidth        the width of the old image
     * @param int        $oldHeight        the height of the old image
     * 
     * @return bool
     */
    public function resize(
        /*string*/ $filePath,
        /*image*/ $oldImage,
        /*int*/ $newX,
        /*int*/ $newY,
        /*int*/ $oldX,
        /*int*/ $oldY,
        /*int*/ $newWidth,
        /*int*/ $newHeight,
        /*int*/ $oldWidth,
        /*int*/ $oldHeight,
        /*int*/ $quality
    )
    {
        $newImage = imagecreatetruecolor($newWidth, $newHeight);
        $success = imagecopyresampled(
            $newImage,
            $oldImage,
            $newX,
            $newY,
            $oldX,
            $oldY,
            $newWidth,
            $newHeight,
            $oldWidth,
            $oldHeight
        );
        $this->saveImage($newImage, $filePath, $quality);
        
        return $success;
    }

    /**
     * Returns the image in the php image type
     *
     * @return image    $image    the image
     */
    public function getImage()
    {
        $image = null ;

        if ($this->_file->getMimeType() == 'image/jpeg') {
            $image = \imagecreatefromjpeg($this->_file->getPath());
        } else if ($this->_file->getMimeType() == 'image/png') {
            $image = \imagecreatefrompng($this->_file->getPath());
        } else if ($this->_file->getMimeType() == 'image/gif') {
            $image = \imagecreatefromgif($this->_file->getPath());
        }

        return $image;
    }

    /**
     * Saves the image
     *
     * @param image      $image        the image to save
     * @param string     $imagePath    the path to save the image
     * @param int        $quality    the quality
     */
    protected function saveImage(
        /*image*/ $image,
        /*string*/ $imagePath,
        /*int*/ $quality
    )
    {
        $mimeType = $this->_file->getMimeType();
        if (file_exists($imagePath)) {
            chmod($imagePath, 0777);
            $finfo = new \finfo(FILEINFO_MIME_TYPE);
            $mimeType = $finfo->file($imagePath);
        }
        
        if ($mimeType == 'image/jpeg') {
            \imagejpeg($image, $imagePath, $quality);
        } else if ($mimeType == 'image/png') {
            \imagepng($image, $imagePath, 0);
        } else if ($mimeType == 'image/gif') {
            \imagegif($image, $imagePath);
        }
    }
    
    public function display()
    {
        $mimeType = $this->_file->getMimeType();
        header('Content-Type: '.$mimeType);
        
        $image = $this->getImage();
        
        if ($mimeType == 'image/jpeg') {
            \imagejpeg($image);
        } else if ($mimeType == 'image/png') {
            \imagepng($image);
        } else if ($mimeType == 'image/gif') {
            \imagegif($image);
        }
        
        exit;
    }

    public function getFileLink()
    {
    	return $this->_file->getFileLink();
    }
    
    public function getImageLink(){
        return str_replace(getWwwDirectory().'/', '', realpath($this->_file->getFileLink()));
    }
    
    public function serialize(/*boolean*/ $asText=true)
    {
        return $this->_file->serialize($asText);
    }

    public function unserialize(/*string*/ $text)
    {
        $this->_file = new File();
        $this->_file->unserialize($text);
    }

    public function toString()
    {
        return $this->_file->toString();
    }

    public static function getSqlType()
    {
        return SqlType::$varchar ;
    }
}
